package com.geek.novel.services.manager

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.text.TextUtils
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import com.geek.novel.R
import com.geek.novel.activity.base.BaseActivity
import com.geek.novel.bo.AppContext
import com.geek.novel.common.Constant
import com.geek.novel.entity.AppVersion
import com.geek.novel.network.RslHandler
import com.geek.novel.service.UpdateService
import com.geek.novel.services.VersionService
import com.geek.novel.ui.progress.NumberProgressBar
import com.geek.novel.utils.*
import com.geek.novel.vo.ApiErrorResult
import com.geek.novel.vo.ApiResult
import java.io.File

/**
 * 更新的管理器
 */
class VersionUpdateManager private constructor() : RslHandler {

    /**单例模式*/
    companion object{
        @SuppressLint("StaticFieldLeak")
        @Volatile
        private var instance: VersionUpdateManager? = null
        fun getInstance(): VersionUpdateManager {
            if(instance == null){
                synchronized(VersionUpdateManager::class.java){
                    if(instance == null){
                        instance = VersionUpdateManager()
                    }
                }
            }
            return instance!!
        }
        fun getInstance(context: BaseActivity): VersionUpdateManager {
            instance = getInstance()
            instance!!.initDialog(context)
            return instance!!
        }
    }

//    private lateinit var context: BaseActivity

    private var versionService: VersionService = VersionService(this)

    private var isChecking = false

    //安装包下载路径
    private var apkPath: String = Constant.ApkPath

    /**弹框对象*/
    private lateinit var dialog: AlertDialog
    /**标题*/
    private lateinit var tvUpdateTitle: TextView
    /**内容*/
    private lateinit var tvUpdateDesc: TextView
    /**更新按钮*/
    private lateinit var btnUpdateVersion: LinearLayout
    /**更新按钮文字*/
    private lateinit var tvUpdateText: TextView
    /**进度条*/
    private lateinit var npbDownloadPercent: NumberProgressBar
    init{
        //判断是否遗留上个版本的安装包并执行删除操作
        this.checkAndDeleteApkFile()
    }


    private fun initDialog(context: BaseActivity){
        //构建弹框
        val builder = AlertDialog.Builder(context, R.style.AlertDialog)
        val updateDialogView = context.layoutInflater.inflate(R.layout.dialog_update_version, null)
        builder.setView(updateDialogView)
        dialog = builder.create()
        //初始化控件
        tvUpdateTitle = updateDialogView.findViewById(R.id.tv_update_title)
        tvUpdateDesc = updateDialogView.findViewById(R.id.tv_update_desc)
        btnUpdateVersion = updateDialogView.findViewById(R.id.btn_update_version)
        tvUpdateText = updateDialogView.findViewById(R.id.tv_update_text)
        npbDownloadPercent = updateDialogView.findViewById(R.id.npb_download_percent)
    }

    /**判断是否遗留上个版本的安装包并执行删除操作*/
    private fun checkAndDeleteApkFile(){
        val version = SPUtil[Constant.SP_VERSION, "0", SPUtil.sysInfo] as String
        if(Constant.versionCode > version.toLong()){
            this.deleteApkFile()
            SPUtil.put(Constant.SP_VERSION, "${Constant.versionCode}", SPUtil.sysInfo)
        }
    }

    /**删除apk文件夹下面的所有文件*/
    private fun deleteApkFile(){
        try {
            val rootFile = File(apkPath)
            if(rootFile.exists()){
                val listFiles = rootFile.listFiles()
                for (listFile in listFiles) {
                    if(listFile.isFile){
                        listFile.delete()
                    }
                }
            }
        } catch (e: Exception) {
            LogCatUtil.e("???", e.message, e)
            ToastUtils.toast(e.message)
        }
    }

    /**是否弹出提示,首页是不需要显示"当前已经是最新版本啦"的提示*/
    private var isToast: Boolean = true
    /**检查更新*/
    fun checkUpdate(toast: Boolean=true){
        //已经获取到版本信息了，检查是否最新
        if(appVersion != null){
            val result = checkForUpdate(appVersion)
            if(result){
                return
            }
        }
        isToast = toast
        if(isChecking){
            return
        }
        isChecking = true
        versionService.checkUpdate()
    }

    /**从服务器加载的版本信息*/
    private var appVersion: AppVersion? = null

    /**判断是否需要更新*/
    private fun checkForUpdate(data: Any?): Boolean{
        if(data != null){
            appVersion = data as AppVersion
            //判断版本号
            val versionCode = CommUtil.getNumeric(appVersion!!.versionCode)
            if(versionCode > Constant.versionCode){
                //需要更新，弹出更新窗口
                openUpdateDialog(appVersion!!)
                return true
            }else{
                if(isToast){
                    ToastUtils.toast("当前已经是最新版本啦！")
                }
            }
        }
        return false
    }

    /**开始更新*/
    private fun startUpdateVersion(){
//        ToastUtils.toast("开始下载")
        //开始下载，之后进行安装
        this.showDownload()
    }


    /**
     * 弹出下载对话框
     */
    private fun showDownload() {
        val context = AppContext.getContext()
        if (CommUtil.isWifiConnected(context)) {// WIFI连接
            downloadApp()
        } else {// 不是WIFI连接
            // 构造对话框
            val builder = AlertDialog.Builder(context)
            builder.setTitle("提示")
            builder.setMessage("当前网络不是连接到wifi网络" + "\n\n是否下载更新？")
            // 更新
            builder.setPositiveButton(R.string.soft_update_btn) { dialog, _ ->
                downloadApp()
                dialog.dismiss()
            }
            // 稍后更新
            builder.setNegativeButton(R.string.soft_update_later) { dialog, _ -> dialog.dismiss() }
            //弹框
            val checkNetDialog = builder.create()
            checkNetDialog.show()
        }

    }


    /**显示进度条*/
    private fun showStartProgress(){
        npbDownloadPercent.visibility = View.VISIBLE
        tvUpdateText.text = "下载中..."
        btnUpdateVersion.setOnClickListener{
            ToastUtils.toast("正在下载中,请稍候")
        }
    }


    /**下载APP*/
    private fun downloadApp(){
        //显示进度条
        this.showStartProgress()
        //开始下载app
        if(appVersion != null){
            //获取下载地址
            val appUrl = appVersion!!.appUrl
            val versionName = appVersion!!.versionName
            val size = java.lang.Float.valueOf(appVersion!!.appSize!!) / 1024f / 1024f

            // 显示下载对话框
            val intent = Intent()
            intent.putExtra("path", apkPath)
            val apkName = this.getApkName()
            intent.putExtra("name", apkName)
            intent.putExtra("info", versionName)
            intent.putExtra("size", CommUtil.getDecimalFormat((size).toDouble()) + "")
            intent.putExtra("url", appUrl)

            val context = AppContext.getContext()
            intent.setClass(context, UpdateService::class.java)
            context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
            context.startService(intent)
        }

    }

    /**更新服务的连接方法*/
    private var connection: ServiceConnection = object : ServiceConnection {
        override fun onServiceDisconnected(name: ComponentName?) {
        }

        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val binder = service as UpdateService.MyBinder

            binder.setDate(object : UpdateService.UpdateProgress {
                override fun update(completed: Boolean, cancel: Boolean, progress: Int, error: Throwable?){
                    if(error != null){
                        ToastUtils.toast(error.message)
                    }
                    if(cancel){
                        checkLocalApk()
                        npbDownloadPercent.visibility = View.INVISIBLE
                    }else if (completed) {
                        checkLocalApk()
                    }else{
                        if(npbDownloadPercent.visibility != View.VISIBLE){
                            //显示进度条
                            showStartProgress()
                        }
                        npbDownloadPercent.progress = progress
                    }
                }
            })

        }
    }


    fun stopService(){
        val context = AppContext.getContext()
        val intent = Intent()
        intent.setClass(context, UpdateService::class.java)
        context.stopService(intent)
    }

    /**获取apk文件的名称*/
    private fun getApkName(): String{
        val apkName = "NovelReader"
        if(this.appVersion == null){
            return "${apkName}.apk"
        }
        return "${apkName}_${this.appVersion!!.versionCode}.apk"
    }

    /**判断本地是否存在apk文件，存在则显示立即安装*/
    private fun checkLocalApk(): Boolean{
        val apkName = this.getApkName()
        val apkFile = File(apkPath, apkName)
        val exists = apkFile.exists()
        if (exists) {
            tvUpdateText.text = "立即安装"
            npbDownloadPercent.visibility = View.INVISIBLE
            //立即安装
            btnUpdateVersion.setOnClickListener{
                this.installApk()
            }
        }else{
            tvUpdateText.text = "立即升级"
            //下载APP进行更新
            btnUpdateVersion.setOnClickListener{
                this.startUpdateVersion()
            }
        }
        return exists
    }

    /**打开更新窗口*/
    @SuppressLint("SetTextI18n")
    private fun openUpdateDialog(version: AppVersion){
        //是否强制更新
        val cancelable = version.mandatory != "1"
        dialog.setCancelable(cancelable)
        dialog.setCanceledOnTouchOutside(cancelable)

        //显示文本
        tvUpdateTitle.text = "有新版本啦： ${version.versionName}"
        tvUpdateDesc.text = this.getVersionDesc(version)

        //判断本地是否存在apk文件，存在则显示立即安装
        this.checkLocalApk()

        //显示弹框
        dialog.show()
    }

    /**获取版本说明*/
    private fun getVersionDesc(version: AppVersion): String{
        var versionDesc = version.versionDesc?:""
        if(TextUtils.isEmpty(versionDesc)){
            versionDesc = "暂无说明"
        }
        return versionDesc.replace("\\n", "\n")
            .replace("<br>", "\n")
            .replace("</br>", "\n")
    }

    private fun resetCheckingFlag(code: Int){
        when(code){
            //检查更新
            Constant.HTTP_KEY_APP_CHECK_UPDATE->{
                isChecking = false
            }
        }
    }


    /**
     * 安装apk
     */
    private fun installApk() {
        val apkName = this.getApkName()
        val apkFile = File(apkPath, apkName)
        if (!apkFile.exists()) {
            return
        }
        FileUtil.installApk(AppContext.getContext(), apkFile)
    }


    override fun onError(code: Int, err: ApiErrorResult) {
        this.resetCheckingFlag(code)
    }
    override fun onSuccess(result: ApiResult, code: Int) {
        this.resetCheckingFlag(code)
        when(code){
            //检查更新
            Constant.HTTP_KEY_APP_CHECK_UPDATE->{
                checkForUpdate(result.getData())
            }
        }
    }
}